TARGET = out

DBG = 1
ifeq ($(DBG), 1)
	BUILD_DIR = dbg
else
	BUILD_DIR = release
endif

OBJECTS_DIR = bin

#编译器
PREFIX = riscv-none-embed-
CC =  $(PREFIX)gcc
# CXX =  $(PREFIX)g++
AS =  $(PREFIX)gcc -x assembler-with-cpp
CP =  $(PREFIX)objcopy
SZ =  $(PREFIX)size --format=berkeley
DUMP= $(PREFIX)objdump
HEX = $(CP) -O ihex
BIN = $(CP) -O binary -S

LIBS :=

#汇编启动文件
ASM_SOURCES = $(wildcard ./Startup/*.s)
ASM_SOURCES += $(wildcard ./FreeRTOS/*.s)

# C文件
C_SOURCES =
C_SOURCES += $(wildcard ./Core/*.c) 
# C_SOURCES += $(wildcard ./Debug/src*.c) 
C_SOURCES += $(wildcard ./User/*.c) 
C_SOURCES += $(wildcard ./Peripheral/*.c) 
C_SOURCES += $(wildcard ./Debug/*.c) 
C_SOURCES += $(wildcard ./FreeRTOS/*.c) 

#链接文件
LDSCRIPT = $(wildcard ./Ld/*.ld)

# C_CPP includes
C_INCLUDES=
C_INCLUDES += $(addprefix -I,./Core)
C_INCLUDES += $(addprefix -I, ./Debug)
C_INCLUDES += $(addprefix -I,./User )
C_INCLUDES += $(addprefix -I,./Peripheral)
C_INCLUDES += $(addprefix -I,./FreeRTOS)

ifeq ($(DBG), 1)
	dbgLevel = -g
else
	dbgLevel = -g0
endif

# C文件编译参数
CFLAGS = -march=rv32imac -mabi=ilp32 -msmall-data-limit=8 -mno-save-restore -Os -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -Wunused -Wuninitialized  $(dbgLevel) 
CFLAGS += $(C_INCLUDES) -std=gnu99 -MMD -MP -MF"$(@:%.o=%.d)" -MT

#asm编译参数
ASFLAGS = -march=rv32imac -mabi=ilp32 -msmall-data-limit=8 -mno-save-restore -Os -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -Wunused -Wuninitialized  $(dbgLevel) -x assembler-with-cpp 
ASFLAGS += $(C_INCLUDES) -MMD -MP -MF"$(@:%.o=%.d)" -MT

# 链接所用参数
LDFLAGS = -march=rv32imac -mabi=ilp32 -msmall-data-limit=8 -mno-save-restore -Os -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -Wunused -Wuninitialized  $(dbgLevel) -T $(LDSCRIPT) $(LIBS) -nostartfiles -Xlinker --gc-sections -Wl,-Map,$(BUILD_DIR)/$(TARGET).map --specs=nano.specs --specs=nosys.specs 

# 默认执行: build all，elf、hex、bin、lst
all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin $(BUILD_DIR)/$(TARGET).dis

# list of ASM program objects
OBJECTS = $(addprefix $(BUILD_DIR)/$(OBJECTS_DIR)/,$(notdir $(ASM_SOURCES:.s=.o)))
vpath %.s $(sort $(dir $(ASM_SOURCES)))

# list of objects
OBJECTS += $(addprefix $(BUILD_DIR)/$(OBJECTS_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
vpath %.c $(sort $(dir $(C_SOURCES)))


# 编译c文件
$(BUILD_DIR)/$(OBJECTS_DIR)/%.o: %.c Makefile | $(BUILD_DIR)/$(OBJECTS_DIR)
	@$(CC) $(CFLAGS)"$(@)" -c -o "$@" "$<"
	@echo compilling $(notdir $(<:.c=.o)) ...

#编译s文件
$(BUILD_DIR)/$(OBJECTS_DIR)/%.o: %.s Makefile | $(BUILD_DIR)/$(OBJECTS_DIR)
	@$(CC) $(ASFLAGS)"$(@)" -c -o $@ $<
	@echo compilling $(notdir $(<:.s=.o)) ...

$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) $(LIBS)
	@$(CC) $(LDFLAGS) -o $@ $^
	@echo Linking and generating excutable elf file ...
# 加入@后可省去路径
	$(SZ) $@

$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf 
	$(HEX) $< $@
	
$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf 
	$(BIN) $< $@	

# 生成反汇编
$(BUILD_DIR)/%.dis:$(BUILD_DIR)/%.elf
	$(DUMP) --all-headers --demangle --disassemble $<  > $@

#我们经常会创建文件去存放不同的文件.常用的一种方法便是借助于shell中的mkdir来创建，
#而且可以用-e来判断文件夹是否存在，决定是否创建。
#说明：当创建的文件不止一层时且都不存在时，需要添加-p参数，否则会报错 no such file or dirctory

$(BUILD_DIR)/$(OBJECTS_DIR):
#	@	@-mkdir $@
	$(shell if [ ! -e $(@) ];then mkdir -p $(@); fi)

clean:
	-rm -fR $(BUILD_DIR)
	-rm -fR $(BUILD_DIR)/$(OBJECTS_DIR)/**

install:$(BUILD_DIR)/out.elf
	-wchOpenocd.exe -f target/wch-riscv.cfg -c init -c halt -c "flash erase_sector wch_riscv 0 last " -c "program $<" -c "verify_image $<" -c wlink_reset_resume -c exit

print:
	@echo $(OBJECTS)
	@echo $(C_SOURCES)
# dependencies依赖关系
-include $(wildcard $(BUILD_DIR)/$(OBJECTS_DIR)/*.d)

# *** EOF ***